// scripts/dev.js
/**
 * 用于打包“开发环境”的脚本
 *
 * 用法示例：
 * node scripts/dev.js --format esm
 * node scripts/dev.js -f cjs reactive
 *
 * - 位置参数（第一个）用于指定要打包的子包名称（对应 packages/<name>）
 * - --format / -f 指定输出格式：esm | cjs | iife（默认为 esm）
 */

import { parseArgs } from 'node:util'
import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import esbuild from 'esbuild'
import { createRequire } from 'node:module'

/**
 * 解析命令行参数
 * allowPositionals: 允许使用位置参数（例如 reactive）
 * options.format: 支持 --format 或 -f，类型为字符串，默认为 'esm'
 */
const {
  values: { format },
  positionals,
} = parseArgs({
  allowPositionals: true,
  options: {
    format: {
      type: 'string',
      short: 'f',
      default: 'esm',
    },
  },
})

/**
 * 在 ESM 模式下创建 __filename / __dirname
 * - ESM 中没有这两个全局变量，因此需要通过 import.meta.url 进行转换
 */
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

/**
 * 在 ESM 中创建一个 require() 函数
 * - 用于加载 CJS 风格的资源（例如 JSON）
 */
const require = createRequire(import.meta.url)

/**
 * 解析要打包的目标
 * - 如果提供了位置参数，则取第一个；否则默认打包 packages/vue
 */
const target = positionals.length ? positionals[0] : 'vue'

/**
 * 入口文件（固定指向 packages/<target>/src/index.ts）
 */
const entry = resolve(__dirname, `../packages/${target}/src/index.ts`)

/**
 * 决定输出文件路径
 * - 命名约定：<target>.<format>.js
 * 例：reactive.cjs.js / reactive.esm.js
 */
const outfile = resolve(__dirname, `../packages/${target}/dist/${target}.${format}.js`)

/**
 * 读取目标子包的 package.json
 * - 常见做法是从中读取 buildOptions.name，作为 IIFE/UMD 的全局变量名
 * - 如果 package.json 中没有 buildOptions，请自行调整
 */
const pkg = require(`../packages/${target}/package.json`)

/**
 * 创建 esbuild 编译上下文并进入 watch 模式
 * - entryPoints: 打包入口
 * - outfile: 打包输出文件
 * - format: 'esm' | 'cjs' | 'iife'
 * - platform: esbuild 的目标平台（'node' | 'browser'）
 * * 这里示范：如果是 cjs，就倾向于 node；否则视为 browser
 * - sourcemap: 方便调试
 * - bundle: 将依赖打包进去（输出为单文件）
 * - globalName: IIFE/UMD 格式下挂载到 window 上的全局名称（esm/cjs 格式下不会用到）
 */
esbuild
  .context({
    entryPoints: [entry],                          // 入口文件
    outfile,                                       // 输出文件
    format,                                        // 输出格式：esm | cjs | iife
    platform: format === 'cjs' ? 'node' : 'browser',// 目标平台：node 或 browser
    sourcemap: true,                               // 生成 source map
    bundle: true,                                  // 打包成单文件
    globalName: pkg.buildOptions?.name,            // IIFE/UMD 会用到；esm/cjs 可忽略
  })
  .then(async (ctx) => {
    // 启用 watch：监听文件变更并自动重新构建
    await ctx.watch()
    console.log(
      `[esbuild] watching "${target}" in ${format} mode → ${outfile}`
    )
  })
  .catch((err) => {
    console.error('[esbuild] build context error:', err)
    process.exit(1)
  })
